package org.gap.jseed.contract;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

import org.gap.jseed.contract.annotation.Condition;
import org.gap.jseed.contract.annotation.Invariant;
import org.gap.jseed.injection.ClassWriter;

public class InvariantValidation extends ValidationWriter {
	private static final String INVARIENT_TEST_ACTIVE = "invarientTestActive";
	private static final String preCheck = "if (!" + INVARIENT_TEST_ACTIVE + ") {\n" +
										   "    " + INVARIENT_TEST_ACTIVE + " = true;\n";
	private static final String postCheck = "    " + INVARIENT_TEST_ACTIVE + " = false;\n" +
										    "}";
	@Override
	public void injectBehavior(ClassWriter javaWriter, Method method, Annotation annotation) {
		Invariant invarient = (Invariant)annotation;
		for (Condition each : invarient.value()) {
			javaWriter.insertBefore(method, preCheck + "    " + createTestCondition(each.value()) +  createPreConditionViolationException(each) + postCheck);
			javaWriter.insertAfter(method, preCheck + "    " + createTestCondition(each.value()) + createPostConditionViolationException(each) + postCheck);
		}
		assureInvarientFieldExists(javaWriter);
	}

	private void assureInvarientFieldExists(ClassWriter javaWriter) {
		if (!javaWriter.isFieldExisting(INVARIENT_TEST_ACTIVE)) {
			javaWriter.addField(boolean.class, INVARIENT_TEST_ACTIVE);
		}
	}

}
